單向雜湊函數(One-Way Hash Function) 是一種能將「任意長度輸入資料」轉換成「固定長度字串輸出」的數學演算法。這個產出的固定長度字串通常稱為雜湊值(Hash Value)或訊息摘要(Message Digest)。
在密碼學中,我們常把雜湊值比喻為資料的「數位指紋(Digital Fingerprint)」,它具備以下三大基本物理特性:
並非所有的雜湊演算法(例如用於 Hash Table 資料結構或 Java 內建的 Object.hashCode())都能用於安全領域。一個合格的密碼學雜湊函數必須嚴格滿足以下三種計算上的不可逆與抗碰撞特性:
| 演算法 | 輸出長度 | 目前安全性狀態 | 技術說明與歷史現況 |
|---|---|---|---|
| MD5 | 128 bits | 完全破譯(極度危險) | 已能在數秒內製造碰撞,嚴重不安全,已被全面廢除。 |
| SHA-1 | 160 bits | 已遭破譯(禁止使用) | Google 於 2017 年展現 SHAttered 實體碰撞攻擊,已淘汰。 |
| SHA-2 | 224 / 256 / 384 / 512 bits | 目前主流業界標準 | 包含 SHA-256 與 SHA-512,屬於 Merkle-Damgård 結構,目前無有效攻擊法。 |
| SHA-3 | 224 / 256 / 384 / 512 bits | 最新 NIST 標準 (Keccak) | 採用全新的海綿結構(Sponge Construction),作為 SHA-2 的安全備援防線。 |
在 Java 中,雜湊函數由 JCA 的核心 Engine Class java.security.MessageDigest 提供支援。
MessageDigest 標準實作範例import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
public class HashDemo {
public static void main(String[] args) throws Exception {
String inputText = "Hello";
// 1. 取得 SHA-256 與 SHA3-256 引擎實體 (Engine Class)
MessageDigest sha2Digest = MessageDigest.getInstance("SHA-256");
MessageDigest sha3Digest = MessageDigest.getInstance("SHA3-256");
// 2. 傳入資料位元組並計算雜湊值
byte[] sha2hashBytes = sha2Digest.digest(inputText.getBytes(StandardCharsets.UTF_8));
byte[] sha3hashBytes = sha3Digest.digest(inputText.getBytes(StandardCharsets.UTF_8));
// 3. 轉為十六進位 (Hex String) 表示
String sha2HexResult = bytesToHex(sha2hashBytes);
String sha3HexResult = bytesToHex(sha3hashBytes);
System.out.println("輸入明文: " + inputText);
System.out.println("SHA-256 雜湊值 (" + sha2hashBytes.length * 8 + " bits): " + sha2HexResult);
System.out.println("SHA3-256 雜湊值 (" + sha3hashBytes.length * 8 + " bits): " + sha3HexResult);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}